package cn.yl.user.server.service.impl;

import cn.blb.service.oss.util.OssConfig;
import cn.yl.api.server.result.Result;
import cn.yl.api.server.util.JwtUtil;
import cn.yl.api.server.util.PasswordUtil;
import cn.yl.api.server.util.UrlUtils;
import cn.yl.user.server.entity.User;
import cn.yl.user.server.entity.dto.UserDto;
import cn.yl.user.server.entity.vo.UserVo;
import cn.yl.user.server.mapper.UserMapper;
import cn.yl.user.server.service.UserService;
import cn.yl.user.server.service.feign.CommentFeignService;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.client.config.utils.MD5;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author yl
 * @since 2022-04-22
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private OssConfig ossConfig;

    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private CommentFeignService commentFeignService;

    @Override
    public Result login(UserVo userVo) {
        if (!StringUtils.isEmpty(userVo.getPhone()) && !StringUtils.isEmpty(userVo.getPassword())) {
            QueryWrapper<User> wrapper = new QueryWrapper<>();
            wrapper.eq("phone", userVo.getPhone());
            User user = this.getOne(wrapper);
            UserDto userDto = new UserDto();
            if (user != null) {
                if (user.getPassword().equals(PasswordUtil.getMD5Password(userVo.getPassword(), user.getSalt()))) {
                    BeanUtils.copyProperties(user, userDto);
                    String jwt = createJWT(user);
                    return Result.ok().setData("item", jwt);
                } else {
                    return Result.error().setMessage("密码错误");
                }
            } else {
                user = new User();
                //todo 图片设置
                BeanUtils.copyProperties(userVo, user);
                user.setName("泡泡新人").setPortrait("images/ad/index1.jpg").setSalt(PasswordUtil.getRandomString(4));
                user.setPassword(PasswordUtil.getMD5Password(user.getPassword(), user.getSalt()));
                this.save(user);
                String jwt = createJWT(user);
                BeanUtils.copyProperties(user, userDto);
                return Result.ok().setData("item", jwt);
            }
        }
        return Result.error().setMessage("不能为空");
    }

    @Override
    public UserDto getUserDtoByJwt(String jwt) {
        try {
            Claims claims = jwtUtil.parseJWT(jwt);
            String subject = claims.getSubject();
            UserDto userDto = JSON.parseObject(subject, UserDto.class);
            User user = this.getById(userDto.getId());
            if (!userDto.getPortrait().contains("https")) {
                userDto.setPortrait(ossConfig.getOssWebUrl() + userDto.getPortrait());
            }
            if (!user.getPortrait().contains("https")) {
                user.setPortrait(ossConfig.getOssWebUrl() + user.getPortrait());
            }
            userDto.setPortrait(user.getPortrait()).setName(user.getName());
            return userDto;
        } catch (ExpiredJwtException e) {
            return null;
        }
    }

    @Override
    public Boolean updateByJwt(UserVo userVo, String jwt) {
        User user = new User();
        Claims claims = jwtUtil.parseJWT(jwt);
        User byId = this.getById(Integer.parseInt(claims.getId()));
        MD5 instance = MD5.getInstance();
        if (userVo.getPassword() != null) {
            if (!instance.getMD5String(byId.getSalt() + userVo.getPassword()).equals(byId.getPassword())) {
                return false;
            }
        }
        if (StringUtils.isEmpty(userVo.getPortrait())) {
            userVo.setPortrait(null);
        }
        if (StringUtils.isEmpty(userVo.getName())) {
            userVo.setName(null);
        }
        if (StringUtils.isEmpty(userVo.getPassword())) {
            userVo.setPassword(null);
        } else {
            Map<String, String> map = PasswordUtil.getMD5Password(userVo.getPassword2());
            userVo.setPassword(map.get("password"));
            user.setSalt(map.get("salt"));
        }
        BeanUtils.copyProperties(userVo, user);
        user.setId(Integer.parseInt(claims.getId()));
        if (userVo.getName() != null) {
            commentFeignService.updateByUserName(user.getId(), user.getName());
        }
        return this.updateById(user);
    }

    @Override
    public synchronized String loginByWechat(String access_token, String openid) throws UnsupportedEncodingException {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        User user = this.getOne(wrapper.eq("phone", openid));
        if (user == null) {
            String infoUrl = "https://api.weixin.qq.com/sns/userinfo?" +
                    "access_token=" + access_token +
                    "&openid=" + openid +
                    "&lang=zh_CN";
            String infoJson = UrlUtils.loadURL(infoUrl);
            HashMap<String, String> map = JSON.parseObject(infoJson, HashMap.class);
            user = new User();
//            user.setName(URLEncoder.encode(map.get("nickname").toString(), "UTF-8"))
//                    .setPortrait(map.get("headimgurl").toString()).setPhone(openid);
            user.setName(map.get("nickname").toString())
                    .setPortrait(map.get("headimgurl").toString()).setPhone(openid);
            baseMapper.insert(user);
        }
        UserDto userDto = new UserDto();
        BeanUtils.copyProperties(user, userDto);
        String jwt = jwtUtil.createJWT(String.valueOf(user.getId()), JSON.toJSONString(userDto), "user");
        return jwt;
    }


    private String createJWT(User user) {
        UserDto userDto = new UserDto();
        BeanUtils.copyProperties(user, userDto);
        String jwt = jwtUtil.createJWT(String.valueOf(user.getId()), JSON.toJSONString(userDto), "user");
        return jwt;
    }

//    private static String getRandomString(int length) {
//        String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
//        Random random = new Random();
//        StringBuffer sb = new StringBuffer();
//        for (int i = 0; i < length; i++) {
//            int number = random.nextInt(62);
//            sb.append(str.charAt(number));
//        }
//        return sb.toString();
//    }
}
